Technical Q&A QA1217
How can I programmatically determine the DPI of the current video mode?


Q: åªç›ÇÃÉrÉfÉIÉÇÅ[ÉhÇà DPIÅi1 ÉCÉìÉ`džÇΩÇËÇÃÉhÉbÉgêîÅjÇÉvÉçÉOÉâÉÄÇ≈îªífÇ∑ÇÈÇ…ÇÕÅAǫǧÇ∑ÇÍÇŒÇÊÇ¢Ç≈ǵÇÂǧǩÅH

A: ÉrÉfÉIÉÇÅ[ÉhÇà DPI Çï‘Ç∑ÇΩÇflÇÃíPìΔÇà API ÇÕdžÇËÇ‹ÇπÇÒÇ™ÅAIOKit Ç®ÇÊÇ— Core Graphics Ç©ÇÁïKóvÇ»èÓïÒÇìæÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅBIOKit Ç≈ÇÕÅAÉÇÉjÉ^ÇÃï®óùìIÇ»ÉTÉCÉYÇÉ~ÉäÉÅÅ[ÉgÉãíPà Ç≈ämîFÇ≈Ç´Ç‹Ç∑ÅBàÍï˚ÅACore Graphics (CG) Ç≈ÇÕÅAåªç›ÇÃÉfÉBÉXÉvÉåÉCâëúìxÇ™ÇÌÇ©ÇËÇ‹Ç∑ÅBÉäÉXÉg 1 Ç…ÅAîCà”ÇÃÉÇÉjÉ^Ç…Ç®ÇØÇÈîCà”ÇÃÉfÉBÉXÉvÉåÉCÉÇÅ[ÉhÇà DPI Çï‘Ç∑ä÷êîÇé¶ÇµÇ‹Ç∑ÅBÉäÉXÉg 2 Ç…ÇÕÅAåªç›ÇÃÉfÉBÉXÉvÉåÉCÉÇÅ[ÉhÇ≈ÉÅÉCÉìÉÇÉjÉ^ÇÃêÖïΩÇ®ÇÊÇ—êÇíº DPI ÇîªífÇ∑ÇÈÇΩÇflÇÃä÷êîÇÃégópï˚ñ@Çé¶ÇµÇ‹Ç∑ÅB



// CFDictionaryRef Ç©ÇÁ int ÇéÊìæÇ∑ÇÈä»à’ä÷êî
static int GetIntFromDictionaryForKey( CFDictionaryRef desc, CFStringRef key )
{
    CFNumberRef value;
    int num = 0;
    if ( (value = CFDictionaryGetValue(desc, key)) == NULL
            || CFGetTypeID(value) != CFNumberGetTypeID())
        return 0;
    CFNumberGetValue(value, kCFNumberIntType, &num);
    return num;
}

CGDisplayErr GetDisplayDPI(
    CFDictionaryRef displayModeDict,
    CGDirectDisplayID displayID,
    double *horizontalDPI, double *verticalDPI )
{
    CGDisplayErr err = kCGErrorFailure;
    io_connect_t displayPort;
    CFDictionaryRef displayDict;

    // óvãÅÇ≥ÇÍÇΩÉfÉBÉXÉvÉåÉCÇÃÇΩÇflÇ… IOKit Ç÷ê⁄ë±èÓïÒÇéÊÇËçûÇfi
    displayPort = CGDisplayIOServicePort( displayID );
    if ( displayPort != MACH_PORT_NULL )
    {
        // DZÇÃÉfÉBÉXÉvÉåÉCDžǬǢǃ IOKit Ç™éùǡǃǢÇÈèÓïÒÇí≤ÇÈ
        displayDict = IOCreateDisplayInfoDictionary(displayPort, 0);
        if ( displayDict != NULL )
        {
            const double mmPerInch = 25.4;
            double horizontalSizeInInches =
                (double)GetIntFromDictionaryForKey(displayDict,
                        CFSTR(kDisplayHorizontalImageSize)) / mmPerInch;
            double verticalSizeInInches =
                (double)GetIntFromDictionaryForKey(displayDict,
                        CFSTR(kDisplayVerticalImageSize)) / mmPerInch;

            // IOKit Ç©ÇÁéÊìæÇµÇΩÉfÉBÉNÉVÉáÉiÉäÇïKÇ∏âï˙Ç∑ÇÈDZÇΔ
            CFRelease(displayDict);

            // DZÇÍÇ≈ÅAdisplayModeDict Ç©ÇÁÇÃèÓïÒÇégóp
            // ǵǃÅAé¿ç€Çà DPI ÇåvéZÇ∑ÇÈDZÇΔÇ™Ç≈Ç´ÇÈ
            *horizontalDPI =
                (double)GetIntFromDictionaryForKey( displayModeDict, kCGDisplayWidth )
                    / horizontalSizeInInches;
            *verticalDPI = (double)GetIntFromDictionaryForKey( displayModeDict,
                    kCGDisplayHeight ) / verticalSizeInInches;
            err = CGDisplayNoErr;
        }
    }
    return err;
}

ÉäÉXÉg 1. ÉXÉNÉäÅ[Éì DPI ÇÃéZèo





double horizontalDPI, verticalDPI;
CGDisplayErr err = GetDisplayDPI( CGDisplayCurrentMode(kCGDirectMainDisplay),
                kCGDirectMainDisplay,
                &horizontalDPI, &verticalDPI );
if ( err == CGDisplayNoErr )
{
    // horizontalDPI ÇΔ verticalDPI Ç≈âΩÇ©Ç∑ÇÈ
}

ÉäÉXÉg 2. ìTå^ìIÇ»égópñ@




[2002 îN 12 åé 2 ì˙]